import { ref, computed } from 'vue';
import type { App } from 'vue';

// 错误类型定义
export interface ApiError {
  code: string | number;
  message: string;
  data?: any;
  timestamp?: number;
}

export interface ErrorHandlerOptions {
  showToast?: boolean;
  customMessage?: string;
  onError?: (error: ApiError) => void;
  retryable?: boolean;
  retryAction?: () => Promise<void>;
}

// 全局错误处理器类
export class ErrorHandler {
  private static instance: ErrorHandler | null = null;
  private errorCount = ref(0);
  private activeRequests = ref(0);
  
  private constructor() {}
  
  public static getInstance(): ErrorHandler {
    if (!ErrorHandler.instance) {
      ErrorHandler.instance = new ErrorHandler();
    }
    return ErrorHandler.instance;
  }
  
  public initialize(_app: App): void {
    // 简化实现，不再需要app实例
  }
  
  // 开始请求计数
  public startRequest(): void {
    this.activeRequests.value++;
  }
  
  // 结束请求计数
  public endRequest(): void {
    this.activeRequests.value = Math.max(0, this.activeRequests.value - 1);
  }
  
  // 处理API错误
  public handleApiError(error: any, options?: ErrorHandlerOptions): ApiError {
    this.errorCount.value++;
    
    let apiError: ApiError = {
      code: 'UNKNOWN',
      message: '未知错误，请稍后重试',
      timestamp: Date.now()
    };
    
    // 解析错误对象
    if (error && typeof error === 'object') {
      if (error.response) {
        // 服务器返回了错误状态码
        const { data, status } = error.response;
        apiError.code = data?.code || status;
        apiError.message = data?.message || data?.msg || `请求失败 (${status})`;
        apiError.data = data;
      } else if (error.request) {
        // 请求已发送但没有收到响应
        apiError.code = 'NETWORK_ERROR';
        apiError.message = '网络连接失败，请检查您的网络设置';
      } else {
        // 请求配置过程中发生的错误
        apiError.code = 'REQUEST_ERROR';
        apiError.message = error.message || '请求处理失败';
      }
    } else {
      apiError.message = String(error);
    }
    
    // 自定义错误消息
    if (options?.customMessage) {
      apiError.message = options.customMessage;
    }
    
    // 显示错误提示
    if (options?.showToast !== false) {
      this.showErrorToast(apiError.message, options);
    }
    
    // 执行自定义错误处理
    if (options?.onError) {
      options.onError(apiError);
    }
    
    console.error('API请求错误:', apiError);
    return apiError;
  }
  
  // 显示错误提示
  private showErrorToast(message: string, _options?: ErrorHandlerOptions): void {
    // 简化实现，不依赖element-plus
    console.error('Error:', message);
  }
  
  // 获取全局错误状态
  public getErrorState() {
    return {
      errorCount: this.errorCount,
      activeRequests: this.activeRequests,
      hasActiveRequests: computed(() => this.activeRequests.value > 0)
    };
  }
}

// Vue插件安装函数
export const ErrorHandlerPlugin = {
  install(vueApp: App) {
    const errorHandler = ErrorHandler.getInstance();
    errorHandler.initialize(vueApp);
    vueApp.config.globalProperties.$errorHandler = errorHandler;
    vueApp.provide('errorHandler', errorHandler);
  }
};

// 组合式函数：useErrorHandler
export function useErrorHandler() {
  const errorHandler = ErrorHandler.getInstance();
  const errorState = errorHandler.getErrorState();
  
  // 封装错误处理方法
  const handleError = async <T>(
    asyncFn: () => Promise<T>,
    options?: ErrorHandlerOptions
  ): Promise<T | null> => {
    errorHandler.startRequest();
    try {
      const result = await asyncFn();
      return result;
    } catch (error) {
      // 处理错误，但不会中断程序执行
      errorHandler.handleApiError(error, options);
      return null;
    } finally {
      errorHandler.endRequest();
    }
  };
  
  // 可重试的错误处理
  const handleErrorWithRetry = async <T>(
    asyncFn: () => Promise<T>,
    options?: ErrorHandlerOptions & {
      maxRetries?: number;
      retryDelay?: number;
    }
  ): Promise<T | null> => {
    const maxRetries = options?.maxRetries || 2;
    const retryDelay = options?.retryDelay || 1000;
    for (let attempt = 0; attempt <= maxRetries; attempt++) {
      try {
        errorHandler.startRequest();
        const result = await asyncFn();
        return result;
      } catch (error) {
        // 如果是最后一次尝试，显示错误
        if (attempt === maxRetries) {
          errorHandler.handleApiError(error, options);
        } else {
          // 等待一段时间后重试
          await new Promise(resolve => setTimeout(resolve, retryDelay * Math.pow(2, attempt)));
        }
      } finally {
        errorHandler.endRequest();
      }
    }
    
    return null;
  };
  
  return {
    handleError,
    handleErrorWithRetry,
    ...errorState
  };
}